//------------------------------------------------------------------------------
// User Management 
// version 1
// Derive from "winestore" version 13
//
// author Luo Xu on 2014.08.02
// Tested successfully.
//
//------------------------------------------------------------------------------

// Save the URL prefix of the current webapp

var config = {
    base: "../../mvc/"
};

//------------------------------------------------------------------------------
// Service Layer
// for business logic including data access and network communication. 
//------------------------------------------------------------------------------

window.UserModel = Backbone.Model.extend({
	// you can also uses urlRoot: config.base +　"api/users". In this way, this 
	// page and js file can be moved into sub folders. 
	urlRoot : config.base + "users",
	
	defaults : {
		"id" : null,
		"loginname" : "",
		"password" : ""
//		"picture" : ""                  
	},

	initialize : function() {
		this.bind('validate', function(model, error) {
			alert(error);
		});
	},
	
	// The returned string will be popup by the browser to notify the user.
	validate : function(attributes) {
		if (attributes.loginname == '') {
			return "loginname can't be null"; 
		}
		if (attributes.password == '') {
			return "password can't be null"; 
		}
	}
});

// window.WineCollectionModel = Backbone.Collection.extend({
//	model : UserModel,
//	url : "api/wines"
// });

// modified by luoxu
// The "client" mode means the collection are fully on the client side. 
// The mode should be "client" to enable client side caching for paging.
//
window.PageableUserCollectionModel = Backbone.PageableCollection.extend({
	model : UserModel,
	url : config.base + "users",
	state : {
		pageSize : 10
	},
	mode : "client" 
});

//------------------------------------------------------------------------------
// View Layer
// for user interaction. Including render the data in the models to webpage
// and accepting the page input to model for saving. 
//------------------------------------------------------------------------------

// In order to guarantee releasing resources when view is closed
//
Backbone.View.prototype.close = function () {
    console.log('Closing view ' + this);
    if (this.beforeClose) {
        this.beforeClose();
    }
    this.remove();
    this.unbind();
};

window.UserView = Backbone.View.extend({
	
    initialize: function() {
    	this.template = _.template($('#tpl_itemdetail').html());
		this.model.on("change", this.render, this);
    },
    
    render: function() {
		$(this.el).html(this.template(this.model.toJSON()));
		return this;
    },

    events: {
        "change input": "onInputChange",
		"click .save": "onSave",
		"click .cancel": "onCancel"
    },

    onInputChange: function(event) {
        var target = event.target;
        console.log('changing ' + target.id + ' from: ' + target.defaultValue + ' to: ' + target.value);
    },

	onSave: function() {
		this.model.set({
			loginname: $('#loginname').val(),
			password: $('#password').val()
		});
		if(!this.model.isValid()){
			alert("loginname and password can't be empty!");
			return false;
		}
		
		// http://stackoverflow.com/questions/16256635/backbone-model-saving-and-callback-issues
		// The model must belong to the pagable wine list
		this.model.save(null, {
			success: function() {
				alert("save successfully!");
				app.navigate('', {trigger: true});
			},
			error: function(error){
				console.log("exception encountered when save data" );
			}
		});

		return false;
	},
	
	onCancel : function(){
		app.navigate('', {trigger :true}); // TODO
	}
});


BackgridDeleteCell = Backgrid.Cell.extend({
	template : _.template('<button class="btn btn-danger">Delete</button>'),
	events : {
		"click" : "onDeleteRow"
	},
	
	onDeleteRow : function(e) {
		e.preventDefault();
		this.model.destroy({
			success : function(model, response) {
				alert('Deleted successfully ' );
			},
			error: function(error){
					console.log("exception encountered when delete data" );
			}
		});
		return false;
	},
	render : function() {
		this.$el.html(this.template());
		this.delegateEvents();
		return this;
	}
});

BackgridEditCell = Backgrid.Cell.extend({
	template : _.template('<a href="#users/<%= this.model.id %>" class="btn btn-primary">Edit</a>'),
	events : {
		"click" : "onEditRow"
	},

	onEditRow : function(e) {
		e.preventDefault();
		//app.navigate("wines/:id", {trigger: true}); 
		app.navigate("users/" + this.model.id, {trigger: true}); 
		return false;
	},

	render : function() {
		this.$el.html(this.template());
		this.delegateEvents();
		return this;
	}
});

BackgridColumns = [{
		// enable the select-all extension of the backgrid component
		name : "",
		cell : "select-row",
		headerCell : "select-all"
	}, {
		name : "id",
		label : "ID",
		editable : false,
		cell : Backgrid.IntegerCell.extend({
			orderSeparator : ''
		})
	}, {
		name : "loginname",
		label : "Login Name",
		editable : false,
		cell : Backgrid.StringCell.extend({
			orderSeparator : ''
		})
	}, {
		name : "password",
		label : "Password",
		editable : false,
		cell : Backgrid.StringCell.extend({
			orderSeparator : ''
		})
	} ];


// Set up a grid to use the pageable collection
window.UserCollectionView = Backbone.View.extend({
	
	grid: Backgrid.Grid,
	
	// The el and model object are passed in when instantiate this object(new this object).
	// model: winelist,
	
	events:{
		'click #addnew': 'onAddnew',
		'click #deleteselected': 'onDeleteSelected',
	},
	
	initialize: function() {
		console.log("UserCollectionView initialized!");
		
		this.template = _.template($("#tpl_itemlist").html());
		
		/*
		this.model.on("change", this.render, this);
		*/
		
		// this.on("reset", function(collection){
		// 	this.render();
		// });
	},

	render: function(){
		grid = new Backgrid.Grid({
			columns: BackgridColumns,
			collection: this.model 
		});

		//this.$el.html(this.template());
		//$(this.el).html(this.template(this.model.toJSON()));
		$(this.el).html(this.template());

		$("#backgrid").html( grid.render().el );
		
		var filter = new Backgrid.Extension.ClientSideFilter({
			collection: this.model,
			fields: ['description']
		});
		$("#backgrid").prepend(filter.render().el);
		var paginator = new Backgrid.Extension.Paginator({
			collection: this.model
		});
		$("#backgrid").append(paginator.render().el);
		
		return this;
	},
	
	onAddnew: function(){
		console.log("addnew selected click");
		$('#objecteditor').html( new UserView({model: new UserModel()}).render().el );
		app.navigate("users/", true);
	},
	
	onDeleteSelected: function(){
		console.log("delete selected click");	

		var selectedModels = grid.getSelectedModels();
		if (selectedModels == null) {
			alert("Please select what you want to delete first!");
		} 
		else if (selectedModels.length > 5){
			alert("This application doesn't allow you delete objects more than 5! You could only select at most 5");
		}
		else{
			_.each(selectedModels, function(model) {
				model.destroy({
					success: function(model,response){
						console.log("delete selected successfully " + model );
					},
					error: function(error){
						console.log("exception encountered when delete data" );
					}
				})
			});
		}
	}
});


// Tile is defined an area containing object list, object detail and their related 
// operations. It's an integration of object collection view and object item view
// together.
//
// TODO
//
window.UserTile = Backbone.View.extend({
	
	// The el will be passed when instantiate this object.
	// el: $("#usertile"),
	
	initialize: function() {
		this.template = _.template($("#tpl_usertile").html());

		this.model.fetch({
    		success : function(collection, resq, options){
    			console.log('UserTile Fetch successfully.');
    		}
    	});

	},

	render: function()
	{
		this.$el.html(this.template());

    	var view = new UserCollectionView({el:"#objecteditor", model: this.model});
    	view.render();
	},
	
	/*
	showList: function(){
		$('#objecteditor').html( new WineCollectionView({}).render().el );
	},
	
	showAddNew: function(){
		$('#objecteditor').html( new UserView({model: new UserModel()}).render().el );
	},
	*/
});


//------------------------------------------------------------------------------
// Controller Definition
//------------------------------------------------------------------------------

var UserManagerApplication = Backbone.Router.extend({

	//Declare the model variable, so that the view and use it later. 
	// winelist = new window.PageableUserCollectionModel();
	userlist: null,
	
	routes : {
		'' : 'getItemList',
		"users/new" : "addNew",
		//"wines/deleteselected" : "deleteSelected",
		"users/:id" : "editItemDetail",
	},

	initialize : function() {
		//var winetile = new window.WineTile({});
		//winetile.render();
		userlist = new window.PageableUserCollectionModel();
	},
	
	showView : function(selector, view) {
		$(selector).empty();
		$(selector).html(view.render().el);
		this.currentView = view;
		return view;
	},
	
	getItemList: function(){
		// attention: I don't know why the backgrid can display data successfully
		// when passing the model here.
		var usertile = new window.UserTile({el: "#usertile", model: userlist});
		usertile.render();
		
		// attention you cannot call app.showView() because the return value of render()
		// method seems not appropriate.
		//app.showView('#winetile', new WineCollectionView());
	},
	
	editItemDetail : function(id) {
		var object = userlist.get(id);
		if (object == null)
		{
			alert("editItemDetail: Failed to get the model object! ");
		}
		else{
			app.showView('#objecteditor', new UserView({model : object}));
		};
	},
	
	addNew : function() {
		/*
		var userView = new UserView({
			el: "itemdetail"
		});
		if (this.currentView)
			this.currentView.close();
		$("itemdetail").html(UserView.render().el);
		this.currentView = userview;
		return userview;
		*/

		console.log("router add new");
		$('#objecteditor').html( new UserView({model: new UserModel()}).render().el );
		//app.showView('#objecteditor', new UserView({model : new UserModel()}));
	},
	
	/*
	deleteSelected : function() {
		console.log("delete selected click");	
		var selectedModels = listview.getSelectedModels();
		if (selectedModels == null) {
			alert("Please select you want to delete!");
			window.history.back();
		} else {
			_.each(selectedModels, function(model) {
//				userlist.remove(model);  change to destroy
				this.model.destroy();
			});
			alert("delete successfully!");
			app.navigate("wines/", true);
		}
	}
	*/
});

$(document).ready(function () {
	app = new UserManagerApplication();
	Backbone.history.start();
});
